package com.na.game.sound;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;

import com.na.game.GameActivity;
import com.na.game.GameManager;
import com.na.game.GameManager.Clazz;
import com.na.game.resource.Destruction;

public class SoundManager implements OnLoadCompleteListener, Destruction, Clazz {

	private SoundPool pool;
	private Map<String, Integer> sounds;
	private AudioManager am;
	private int maxVol;
	private boolean inited;
	private List<Integer> dontPlay;
	private ExecutorService executor;
	
	public SoundManager(Context context) {
		try {
			pool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
			sounds = new HashMap<String, Integer>();
			pool.setOnLoadCompleteListener(this);
			am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
			maxVol = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
			dontPlay = new ArrayList<Integer>(2);
			executor = Executors.newCachedThreadPool();
			inited = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void play(final String assetsPath) {
		if (!inited) {
			return;
		}
		executor.execute(new Runnable() {
			@Override
			public void run() {
				synchronized (sounds) {
					Integer soundId = sounds.get(assetsPath);
					if (soundId != null) {
						play(soundId.intValue());
					} else {
						load(assetsPath, true);
					}
				}
			}
		});
	}
	
	public void load(String assetsPath, boolean play) {
		synchronized (sounds) {
			if (!sounds.containsKey(assetsPath)) {
				try {
					AssetFileDescriptor afd = GameManager.get(GameActivity.class).getAssets().openFd(assetsPath);
					int id = pool.load(afd, 1);
					sounds.put(assetsPath, Integer.valueOf(id));
					if (!play) {
						dontPlay.add(Integer.valueOf(id));
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void play(int id) {
		if (!inited) {
			return;
		}
		int vol = am.getStreamVolume(AudioManager.STREAM_MUSIC);
		float v = (float) vol / maxVol;
		pool.play(id, v, v, 0, 0, 1.0f);
	}
	
	public boolean isLoaded(String assetsPath) {
		return sounds.containsKey(assetsPath);
	}
	
	@Override
	public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
		if (status == 0 && !dontPlay.remove(Integer.valueOf(sampleId))) {
			play(sampleId);
		}
	}

	@Override
	public void destroy() {
		if (inited) {
			pool.release();
			pool = null;
			sounds = null;
			am = null;
		}
	}
	
	@Override
	public Class<?> getClazz() {
		return getClass();
	}
}
